package ui;

import modelsa.Connection;
import modelsa.SearchCriteria;
import modelsa.TransUtils;
import org.openqa.selenium.firefox.FirefoxDriver;
import reservation.CityHours;
import reservation.ReservationMaker;
import reservation.WebUtils;
import ui.util.LabelProvider;
import ui.util.ListCellRendererWithLP;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class MainWindow extends JFrame {

    private final List<Connection> connections;
    private JPanel panelForCheckboxes;
    private JTextField dateTextField;
    private JComboBox connectionCombobox;
    private JTextField placesTextField;
    private JButton reservationButton;
    private JPanel mainPanel;

    public MainWindow(String title, List<Connection> connections) throws HeadlessException {
        super(title);
        this.connections = connections;
        setSize(400, 400);
        createContent();
    }

    private void createContent() {
        final GridLayout layout = new GridLayout(2, 1);

        mainPanel = new JPanel();
        mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        mainPanel.setLayout(new GridLayout(9, 2));

        add(mainPanel);
        setLayout(layout);

        mainPanel.add(new JLabel("Datum"));
        dateTextField = new JTextField();
        dateTextField.setText(SimpleDateFormat.getDateInstance(DateFormat.SHORT).format(new Date()));
        mainPanel.add(dateTextField);

        mainPanel.add(new JLabel("Spojeni = Od - do"));

        connectionCombobox = createComboboxForConnection(mainPanel);
        mainPanel.add(connectionCombobox);

        final JTextField refreshTextField = createRefreshTextField();
        mainPanel.add(new JLabel("Čas občerstvení [s]"));
        mainPanel.add(refreshTextField);

        mainPanel.add(new JLabel("Pocet mist"));
        placesTextField = new JTextField();
        placesTextField.setText("1");
        mainPanel.add(placesTextField);

        reservationButton = new JButton("REZERVOVAT");
        mainPanel.add(reservationButton);
        reservationButton.setEnabled(false);

        reservationButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                provideReservation();
            }
        });

        panelForCheckboxes = new JPanel();
        panelForCheckboxes.setLayout(new GridLayout(15, 1));
        add(panelForCheckboxes);

        refreshPanelForCheckboxes((Connection) connectionCombobox.getItemAt(0));
    }

    private JComboBox createComboboxForConnection(JPanel mainPanel) {
        JComboBox connectionCombobox1 = new JComboBox(connections.toArray());

        connectionCombobox1.setRenderer(new ListCellRendererWithLP(connectionCombobox1.getRenderer(),
                new LabelProvider<Connection>() {
                    @Override
                    public String toString(Connection element) {
                        return element.getFrom() + "   " + element.getTo();
                    }
                }));

        connectionCombobox1.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                final Object item = e.getItem();
                refreshPanelForCheckboxes((Connection) item);
                reservationButton.setEnabled(false);
                panelForCheckboxes.updateUI();
            }
        });
        return connectionCombobox1;
    }

    private JTextField createRefreshTextField() {
        final JTextField refreshRateTextField = new JTextField();
        refreshRateTextField.setText("25");
        refreshRateTextField.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                try {
                    final int i = Integer.parseInt(refreshRateTextField.getText());
                    WebUtils.request = i;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        return refreshRateTextField;
    }

    private void provideReservation() {
        final List<Integer> minutesInDay = getMinutesInDay();

        final Connection selectedItem = (Connection) connectionCombobox.getSelectedItem();
        final SearchCriteria searchCriteria = new SearchCriteria(dateTextField.getText(),
                selectedItem.getFrom(), selectedItem.getTo(),
                minutesInDay.toArray(new Integer[0])
        );

        mainPanel.removeAll();
        remove(panelForCheckboxes);
        final ReservationMadeListener reservationMadeListener = new ComponentForInfo(searchCriteria, mainPanel);
        mainPanel.updateUI();
        repaint();
        doLayout();


        new Thread(new Runnable() {
            @Override
            public void run() {
                final ReservationMaker reservationMaker = new ReservationMaker(new FirefoxDriver());
                try {
                    reservationMaker.makeReservation(searchCriteria, reservationMadeListener);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(0);
                }
            }
        }).start();
    }

    private List<Integer> getMinutesInDay() {
        final List<Integer> integers = new ArrayList<Integer>();

        int places = Integer.parseInt(placesTextField.getText());

        final Component[] components = panelForCheckboxes.getComponents();
        for (final Component component : components) {
            final JCheckBox jCheckBox = (JCheckBox) component;
            if (jCheckBox.isSelected()) {
                final String text = jCheckBox.getText();
                for (int i = 0; i < places; i++) {
                    integers.add(TransUtils.stringToMinuteOfDay(text));
                }
            }
        }
        return integers;
    }

    public void refreshPanelForCheckboxes(Connection connection) {
        panelForCheckboxes.removeAll();
        final List<Integer> hoursForCity = CityHours.getHoursForConnection(connection);
        for (Integer integer : hoursForCity) {
            final String text = integer / 60 + ":" + integer % 60;
            final JCheckBox comp = new JCheckBox(text);
            comp.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    updateButtonEnable();
                }
            });
            panelForCheckboxes.add(comp);
        }
    }

    private void updateButtonEnable() {
        final Component[] components = panelForCheckboxes.getComponents();
        boolean enable = false;
        for (final Component component : components) {
            final JCheckBox jCheckBox = (JCheckBox) component;
            if (jCheckBox.isSelected()) {
                enable = true;
            }
        }
        reservationButton.setEnabled(enable);
    }


}
